package org.rslai.autotest.core.page.impl;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Point;
import org.rslai.autotest.core.page.AbstractHelper;
import org.rslai.autotest.core.page.Actions;

/**
 * Actions处理方法实现类 
 * @author rslai
 */
public class ActionsImpl extends AbstractHelper implements Actions {

	@Override
	public void mouseMove(By by) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.moveToElement(this.driver().findElement(by));
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void mouseMove(By by, int xOffset, int yOffset) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.moveToElement(this.driver().findElement(by), xOffset, yOffset);
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void mouseMove(int xOffset, int yOffset) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.moveByOffset(xOffset, yOffset);
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void mouseOver(By by) {
		this.mouseMove(by);

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void mouseOut(By by) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.moveToElement(super.driver().findElement(by), -10, -10);
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void click(By by) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.click(this.driver().findElement(by));
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void click(By by, int xOffset, int yOffset) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.moveToElement(this.driver().findElement(by), xOffset, yOffset);
		action.click();
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void doubleClick(By by) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		action.doubleClick(super.driver().findElement(by));
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void doubleClick(By by, int xOffset, int yOffset) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		action.moveToElement(super.driver().findElement(by), xOffset, yOffset);
		action.doubleClick(super.driver().findElement(by));
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void contextMenu(By by) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		action.contextClick(super.driver().findElement(by));
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void contextMenu(By by, int xOffset, int yOffset) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		action.moveToElement(super.driver().findElement(by), xOffset, yOffset);
		action.contextClick(super.driver().findElement(by));
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	/**
	 * 单击指定键
	 * @param key 指定键
	 */
	private void sendKeys(Keys key) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		action.sendKeys(key).perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	/**
	 * 在某个对象上单击指定键
	 * @param by 指定对象
	 * @param key 指定键
	 */
	private void sendKeys(By by, Keys key) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		action.sendKeys(super.driver().findElement(by), key).perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void enterPress() {
		this.sendKeys(Keys.ENTER);
	}

	@Override
	public void enterPress(By by) {
		this.sendKeys(by, Keys.ENTER);
	}

	@Override
	public void tabPress() {
		this.sendKeys(Keys.TAB);
	}

	@Override
	public void tabPress(By by) {
		this.sendKeys(by, Keys.TAB);
	}

	@Override
	public void backspacePress() {
		this.sendKeys(Keys.BACK_SPACE);
	}

	@Override
	public void backspacePress(By by) {
		this.sendKeys(by, Keys.BACK_SPACE);
	}

	@Override
	public void keyCombination(KeyOperation ... keyOperations) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		
		for (KeyOperation operation : keyOperations) {
			switch (operation.getType()) {
			case KeyOperation.KEY_DOWN:
				action.keyDown(operation.getKey());
				break;
			case KeyOperation.KEY_UP:
				action.keyUp(operation.getKey());
				break;
			case KeyOperation.SENDKEYS:
				action.sendKeys(operation.getKey());
				break;
			default:
				;
			}
		}

		action.release();
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}
	
	@Override
	public void keyCombination(By by, KeyOperation ... keyOperations) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(super.driver());
		
		for (KeyOperation operation : keyOperations) {
			switch (operation.getType()) {
			case KeyOperation.KEY_DOWN:
				action.keyDown(super.driver().findElement(by), operation.getKey());
				break;
			case KeyOperation.KEY_UP:
				action.keyUp(super.driver().findElement(by), operation.getKey());
				break;
			case KeyOperation.SENDKEYS:
				action.sendKeys(super.driver().findElement(by), operation.getKey());
				break;
			default:
				;
			}
		}

		action.release();
		action.perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void drag(By by, int xOffset, int yOffset) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.clickAndHold(this.driver().findElement(by)).moveByOffset(xOffset, yOffset).perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void drag(By source, By target) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.clickAndHold(this.driver().findElement(source)).moveToElement(this.driver().findElement(target)).perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void drag(By source, By target, int xOffset, int yOffset) {
		Point sourcePoint = this.driver().findElement(source).getLocation();
		Point targetPoint = this.driver().findElement(target).getLocation();

		int sourceXOffset = targetPoint.x - sourcePoint.x + xOffset;
		int sourceYOffset = targetPoint.y - sourcePoint.y + yOffset;

		this.drag(source, sourceXOffset, sourceYOffset);
	}

	@Override
	public void dragAndDrop(By by, int xOffset, int yOffset) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.dragAndDropBy(this.driver().findElement(by), xOffset, yOffset).perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void dragAndDrop(By source, By target) {
		org.openqa.selenium.interactions.Actions action = new org.openqa.selenium.interactions.Actions(this.driver());
		action.dragAndDrop(this.driver().findElement(source), this.driver().findElement(target)).perform();

		this.sleep(super.conf.getDriverPlaybackSpeed()); // 设置回放速度
	}

	@Override
	public void dragAndDrop(By source, By target, int xOffset, int yOffset) {
		Point sourcePoint = this.driver().findElement(source).getLocation();
		Point targetPoint = this.driver().findElement(target).getLocation();

		int sourceXOffset = targetPoint.x - sourcePoint.x + xOffset;
		int sourceYOffset = targetPoint.y - sourcePoint.y + yOffset;

		this.dragAndDrop(source, sourceXOffset, sourceYOffset);
	}

}
